using System;
using System.ComponentModel;
using System.DirectoryServices;
using System.Collections.Generic;

namespace RollManager.Library.ActionSteps
{
    [Serializable]
    public class AddHostHeadersStep : ActionStep
    {
        private string m_siteName = StepConstants.NAME;
        private string[] m_headers = new string[ 0 ];
        private int m_port = 80;

        [DisplayName( "Site Name" )]
        [Description( "The site name to which the headers are added." )]
        public string SiteName
        {
            get
            {
                return m_siteName;
            }
            set
            {
                if( string.IsNullOrEmpty( value ) )
                {
                    throw new ArgumentException( "Site Name cannot be empty." );
                }
                else
                {
                    m_siteName = value.Trim();
                }
            }
        }

        [DisplayName( "Host Headers" )]
        [Description( "The host headers to add to the site." )]
        public string[] HostHeaders
        {
            get
            {
                return m_headers;
            }
            set
            {
                m_headers = value;
            }
        }

        [Description( "The port to use for the headers." )]
        public int Port
        {
            get
            {
                return m_port;
            }
            set
            {
                m_port = value;
            }
        }

        public override string Name
        {
            get { return "Add Host Headers"; }
        }

        protected override void Run()
        {
            DirectoryEntry site = new DirectoryEntry( string.Format( "{0}/{1}", IISDir, getWebsiteId() ) );
         
            //Get everything currently in the serverbindings propery. 
            List<Object> serverBindings = new List<object>( (Object[]) site.InvokeGet( "ServerBindings" ) );
            bool addedHeader = false;
            
            //Add the new bindings
            foreach( string hostHeader in m_headers )
            {
                string header = string.Format( ":{0}:{1}", m_port, hostHeader );
                if( !serverBindings.Contains( header ) )
                {
                    serverBindings.Add( header );
                    addedHeader = true;
                }
            }

            if( addedHeader )
            {
                //Write to metabase
                serverBindings.TrimExcess();
                site.InvokeSet( "ServerBindings", new object[] { serverBindings.ToArray() } );

                //Commit the changes
                site.CommitChanges();
            }
        }

        protected override void Simulate()
        {
            // Check for site on server
            getWebsiteId();

            Progress.AddFormat( "Simulated adding headers to {0}.", m_siteName );
        }

        private string IISDir
        {
            get
            {
                return string.Format( "IIS://{0}/w3svc", CurrentServer );
            }
        }

        private string getWebsiteId()
        {
            DirectoryEntry w3svc = new DirectoryEntry( IISDir );

            foreach( DirectoryEntry de in w3svc.Children )
            {
                if( de.SchemaClassName == "IIsWebServer" && de.Properties[ "ServerComment" ][ 0 ].ToString() == m_siteName )
                {
                    return de.Name;
                }

            }

            throw new Exception( string.Format( "Site {0} not found.", m_siteName ) );
        }
    }
}
